using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace XnaUtility.AI.FSM
{
    public class FSM_Machine : FSM_State
    {

        protected FSM_State curState;
        protected FSM_State defaultState;
        protected FSM_State targetState;
        protected int targetStateID;
        protected int curStateID;
        protected Dictionary<int, FSM_State> states;

        override public void OnEnter()
        {
            throw new NotImplementedException();
        }

        override public void OnExit()
        {
            throw new NotImplementedException();
        }

        override public void Update(GameTime gameTime)
        {
            throw new NotImplementedException();
        }

        override public void Init()
        {
            throw new NotImplementedException();
        }

        override public int CheckTransitions()
        {
            throw new NotImplementedException();
        }

        public virtual void UpdateMachine(GameTime gameTime)
        {
            //if no states, don't do anthing
            if (states.Count == 0)
            {
                return;
            }

            //if no current and no default, there's nothing that can be done
            if (curState == null)
            {
                curState = defaultState;
                if (curState == null)
                {
                    return;
                }
            }            

            //check for transitions
            curStateID = curState.StateID;
            targetStateID = curState.CheckTransitions();
            if (curStateID != targetStateID)
            {
                targetState = states[targetStateID];
                if (targetState == null)
                {
                    //er, this shouldn't have happened
                    throw new Exception("Failed to transfer to state");
                }
                else
                {
                    curState.OnExit();
                    curState = targetState;                    
                    targetState.OnEnter();
                }

            }

            //update the state
            curState.Update(gameTime);
        }

        public FSM_Machine(IBrain newBrain) : base(newBrain)     
        {
            states = new Dictionary<int, FSM_State>();
        }

        public void SetDefaultState(FSM_State value)
        {
            defaultState = value;
        }

        public bool SetDefaultState(int stateID)
        {
            defaultState = states[stateID];
            if (defaultState == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public void AddState(FSM_State value)
        {
            states.Add(value.StateID, value);
        }

        public void ClearStates()
        {
            states.Clear();
        }

        public void InitAllStates()
        {
            foreach (KeyValuePair<int,FSM_State> curPair in states)
            {
                curPair.Value.Init();
            }
        }
    }
}
